/**
 * 广寒宫
 * 网址:www.guanghangong.xyz
 */
package org.moon.framework.autoconfigure.tenant.aop;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.moon.framework.autoconfigure.config.SpringContextConfig;
import org.moon.framework.autoconfigure.datasource.domain.MoonDataSource;
import org.moon.framework.autoconfigure.datasource.routing.DynamicDataSourceContextHolder;
import org.moon.framework.autoconfigure.exception.domain.MoonException;
import org.moon.framework.autoconfigure.mybatisplus.props.JdbcProperties;
import org.moon.framework.autoconfigure.tenant.domain.TenantDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 动态数据源(多租户)
 * @author moon
 */
public interface ITenantAspect {

    public static Map<Object, Object> dataSourcesMap = new ConcurrentHashMap<>(10);

    Logger logger = LoggerFactory.getLogger(ITenantAspect.class);

    /**
     * 根据名称初始化数据源
     * 首先从缓存里取，如果取不到则重新构建一个
     */
    default void changeDataSourceByName(String tenantCode,String applicationName){
        String dsName = tenantCode + StringPool.DASH + applicationName;
        HikariDataSource hikariDataSource = (HikariDataSource)dataSourcesMap.get(dsName);
        if(hikariDataSource!=null){
            DynamicDataSourceContextHolder.setDataSourceType(dsName,dataSourcesMap);
            return;
        }
        String sql = "select driver_class as driverClass, url as jdbcUrl, user_name as userName, password from sys_datasource t LEFT JOIN sys_tenant_datasource td on(t.id=td.datasource_id) where t.is_delete = 0 and td.is_delete = 0 and tenant_code=? and application_name=?";
        List<TenantDataSource> tdsList = SpringContextConfig.getBean(JdbcTemplate.class).query(sql,new Object[]{tenantCode,applicationName},new BeanPropertyRowMapper<>(TenantDataSource.class));
        TenantDataSource dataSource = DataAccessUtils.uniqueResult(tdsList);
        JdbcProperties jdbcProperties = new JdbcProperties();
        if(dataSource!=null){
            jdbcProperties.setUsername(dataSource.getUserName());
            jdbcProperties.setPassword(dataSource.getPassword());
            jdbcProperties.setUrl(dataSource.getJdbcUrl());
            jdbcProperties.setDriverClassName(dataSource.getDriverClass());
        }else{
            jdbcProperties = SpringContextConfig.getBean(JdbcProperties.class);
            logger.warn("租户【"+tenantCode+"】没有为服务【"+applicationName+"】配置数据源,系统将启用默认数据源");
        }
        hikariDataSource = DynamicDataSourceContextHolder.buildDataSource(jdbcProperties);
        dataSourcesMap.put(dsName, hikariDataSource );
        DynamicDataSourceContextHolder.setDataSourceType(dsName,dataSourcesMap);
    }
}
